package com.gitee.qdbp.base.orm.mybatis.converter;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * JSONList格式转换
 *
 * @author zhaohuihua
 * @version 170503
 */
public abstract class JsonBeanListHandler<T> extends BaseTypeHandler<List<T>> {

    private List<String> ignoreFields;

    public abstract Class<T> getBeanType();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType)
            throws SQLException {
        JSONArray array = (JSONArray) JSON.toJSON(parameter);
        if (ignoreFields != null && !ignoreFields.isEmpty() && array != null && !array.isEmpty()) {
            for (Object item : array) {
                if (item instanceof Map) {
                    Map<?, ?> json = (Map<?, ?>) item;
                    for (String field : ignoreFields) {
                        json.remove(field);
                    }
                }
            }
        }
        ps.setString(i, JSON.toJSONString(array));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return toJsonObject(rs.getString(columnName));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return toJsonObject(rs.getString(columnIndex));
    }

    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return toJsonObject(cs.getString(columnIndex));
    }

    private List<T> toJsonObject(String string) {
        if (VerifyTools.isBlank(string)) {
            return null;
        }

        return JSON.parseArray(string, getBeanType());
    }

    public List<String> getIgnoreFields() {
        return ignoreFields;
    }

    public void setIgnoreFields(List<String> ignoreFields) {
        this.ignoreFields = ignoreFields;
    }

    public void addIgnoreField(String... ignoreFields) {
        if (ignoreFields != null && ignoreFields.length > 0) {
            if (this.ignoreFields == null) {
                this.ignoreFields = new ArrayList<>();
            }
            this.ignoreFields.addAll(Arrays.asList(ignoreFields));
        }
    }
}
